/**
 * @file SheriffManager.js
 * @description 警长管理模块 - 处理警长竞选、投票和警徽传递
 */

import { SHERIFF_CONFIG, TAGS } from '../config/constants.js';

/**
 * 警长管理器类
 */
export class SheriffManager {
    constructor(game) {
        this.game = game;
        this.candidates = []; // 竞选候选人列表
        this.votes = {}; // 投票记录 { voterId: candidateId }
        this.sheriffId = null; // 当前警长的userId
        this.electionPhase = 'not_started'; // not_started, registration, voting, completed
    }

    /**
     * 检查是否启用警长功能
     * @returns {boolean}
     */
    isEnabled() {
        const alivePlayers = this.game.players.filter(p => p.isAlive);
        return SHERIFF_CONFIG.ENABLED && alivePlayers.length >= SHERIFF_CONFIG.MIN_PLAYERS;
    }

    /**
     * 开始警长竞选
     */
    startElection() {
        if (!this.isEnabled()) {
            return { success: false, message: '当前游戏人数不足，无法启用警长竞选。' };
        }

        this.electionPhase = 'registration';
        this.candidates = [];
        this.votes = {};

        return {
            success: true,
            message: '【警长竞选】开始警长竞选！有意竞选的玩家请在60秒内发送"#竞选警长"参与竞选。'
        };
    }

    /**
     * 玩家报名竞选警长
     * @param {string} userId - 玩家ID
     * @returns {object} 操作结果
     */
    registerCandidate(userId) {
        if (this.electionPhase !== 'registration') {
            return { success: false, message: '当前不在警长竞选报名阶段。' };
        }

        const player = this.game.players.find(p => p.userId === userId && p.isAlive);
        if (!player) {
            return { success: false, message: '你不在游戏中或已经死亡。' };
        }

        if (this.candidates.includes(userId)) {
            return { success: false, message: '你已经报名竞选了。' };
        }

        this.candidates.push(userId);
        return {
            success: true,
            message: `${player.nickname}(${player.tempId}号) 参与警长竞选！当前候选人数：${this.candidates.length}`
        };
    }

    /**
     * 结束报名，开始投票
     */
    startVoting() {
        if (this.candidates.length === 0) {
            this.electionPhase = 'completed';
            return {
                success: false,
                message: '没有玩家参与警长竞选，本局游戏将不设警长。'
            };
        }

        if (this.candidates.length === 1) {
            // 只有一人竞选，直接当选
            this.sheriffId = this.candidates[0];
            this.electionPhase = 'completed';
            const sheriff = this.game.players.find(p => p.userId === this.sheriffId);
            sheriff.tags = sheriff.tags || [];
            sheriff.tags.push(TAGS.SHERIFF);

            return {
                success: true,
                message: `只有一人参与竞选，${sheriff.nickname}(${sheriff.tempId}号) 自动当选警长！🎖️`,
                sheriffId: this.sheriffId
            };
        }

        this.electionPhase = 'voting';
        this.votes = {};

        let candidateInfo = this.candidates.map(userId => {
            const player = this.game.players.find(p => p.userId === userId);
            return `${player.tempId}号 ${player.nickname}`;
        }).join('\n');

        return {
            success: true,
            message: `【警长投票】\n竞选候选人：\n${candidateInfo}\n\n请所有玩家发送"#投警长 [编号]"为候选人投票（60秒）。`
        };
    }

    /**
     * 玩家投票
     * @param {string} voterId - 投票人ID
     * @param {string} candidateId - 候选人编号
     * @returns {object} 操作结果
     */
    vote(voterId, candidateId) {
        if (this.electionPhase !== 'voting') {
            return { success: false, message: '当前不在投票阶段。' };
        }

        const voter = this.game.players.find(p => p.userId === voterId && p.isAlive);
        if (!voter) {
            return { success: false, message: '你不在游戏中或已经死亡。' };
        }

        const candidate = this.game.players.find(p => p.tempId === candidateId && this.candidates.includes(p.userId));
        if (!candidate) {
            return { success: false, message: '无效的候选人编号。' };
        }

        this.votes[voterId] = candidate.userId;
        return {
            success: true,
            message: `你已投票给 ${candidate.tempId}号。`
        };
    }

    /**
     * 统计投票结果并选出警长
     * @returns {object} 选举结果
     */
    tallyVotes() {
        const voteCount = {};
        this.candidates.forEach(candidateId => {
            voteCount[candidateId] = 0;
        });

        // 统计票数
        for (const voterId in this.votes) {
            const candidateId = this.votes[voterId];
            if (voteCount[candidateId] !== undefined) {
                voteCount[candidateId]++;
            }
        }

        // 找出最高票数
        let maxVotes = 0;
        let winners = [];
        for (const candidateId in voteCount) {
            if (voteCount[candidateId] > maxVotes) {
                maxVotes = voteCount[candidateId];
                winners = [candidateId];
            } else if (voteCount[candidateId] === maxVotes) {
                winners.push(candidateId);
            }
        }

        // 处理平票情况
        if (winners.length > 1) {
            // 随机选择一个（也可以改成pk再投票）
            this.sheriffId = winners[Math.floor(Math.random() * winners.length)];
            const sheriff = this.game.players.find(p => p.userId === this.sheriffId);
            sheriff.tags = sheriff.tags || [];
            sheriff.tags.push(TAGS.SHERIFF);
            this.electionPhase = 'completed';

            let voteDetails = this.candidates.map(cId => {
                const player = this.game.players.find(p => p.userId === cId);
                return `${player.tempId}号 ${player.nickname}: ${voteCount[cId]}票`;
            }).join('\n');

            return {
                success: true,
                message: `【警长选举结果】\n${voteDetails}\n\n出现平票，通过抽签决定，恭喜 ${sheriff.nickname}(${sheriff.tempId}号) 当选警长！🎖️`,
                sheriffId: this.sheriffId
            };
        }

        // 正常选出警长
        this.sheriffId = winners[0];
        const sheriff = this.game.players.find(p => p.userId === this.sheriffId);
        sheriff.tags = sheriff.tags || [];
        sheriff.tags.push(TAGS.SHERIFF);
        this.electionPhase = 'completed';

        let voteDetails = this.candidates.map(cId => {
            const player = this.game.players.find(p => p.userId === cId);
            return `${player.tempId}号 ${player.nickname}: ${voteCount[cId]}票`;
        }).join('\n');

        return {
            success: true,
            message: `【警长选举结果】\n${voteDetails}\n\n恭喜 ${sheriff.nickname}(${sheriff.tempId}号) 当选警长！🎖️`,
            sheriffId: this.sheriffId
        };
    }

    /**
     * 获取当前警长
     * @returns {object|null} 警长玩家对象
     */
    getSheriff() {
        if (!this.sheriffId) return null;
        return this.game.players.find(p => p.userId === this.sheriffId);
    }

    /**
     * 检查玩家是否是警长
     * @param {string} userId - 玩家ID
     * @returns {boolean}
     */
    isSheriff(userId) {
        return this.sheriffId === userId;
    }

    /**
     * 警长传递警徽
     * @param {string} targetPlayerId - 目标玩家编号
     * @returns {object} 操作结果
     */
    transferBadge(targetPlayerId) {
        const targetPlayer = this.game.players.find(p => p.tempId === targetPlayerId && p.isAlive);
        if (!targetPlayer) {
            return { success: false, message: '目标玩家无效或已死亡。' };
        }

        // 移除旧警长的标签
        const oldSheriff = this.getSheriff();
        if (oldSheriff && oldSheriff.tags) {
            oldSheriff.tags = oldSheriff.tags.filter(tag => tag !== TAGS.SHERIFF);
        }

        // 设置新警长
        this.sheriffId = targetPlayer.userId;
        targetPlayer.tags = targetPlayer.tags || [];
        targetPlayer.tags.push(TAGS.SHERIFF);

        return {
            success: true,
            message: `警徽已传递给 ${targetPlayer.nickname}(${targetPlayer.tempId}号)！`,
            newSheriffId: this.sheriffId
        };
    }

    /**
     * 获取投票权重
     * @param {string} userId - 玩家ID
     * @returns {number} 投票权重
     */
    getVoteWeight(userId) {
        if (this.isSheriff(userId)) {
            return SHERIFF_CONFIG.VOTE_WEIGHT;
        }
        return 1;
    }

    /**
     * 警长死亡处理
     */
    onSheriffDeath() {
        if (!this.sheriffId) return null;

        const sheriff = this.game.players.find(p => p.userId === this.sheriffId);
        if (sheriff && !sheriff.isAlive) {
            return {
                success: true,
                message: `警长 ${sheriff.nickname}(${sheriff.tempId}号) 已死亡，请通过私聊发送"#传递警徽 [编号]"传递警徽给其他存活玩家。`,
                sheriffId: this.sheriffId
            };
        }
        return null;
    }

    /**
     * 序列化为JSON（用于保存游戏状态）
     */
    toJSON() {
        return {
            candidates: this.candidates,
            votes: this.votes,
            sheriffId: this.sheriffId,
            electionPhase: this.electionPhase
        };
    }

    /**
     * 从JSON恢复（用于加载游戏状态）
     */
    static fromJSON(game, data) {
        const manager = new SheriffManager(game);
        manager.candidates = data.candidates || [];
        manager.votes = data.votes || {};
        manager.sheriffId = data.sheriffId || null;
        manager.electionPhase = data.electionPhase || 'not_started';
        return manager;
    }
}

